
#ifndef __TETRIS_APP_H__
#define __TETRIS_APP_H__

#include "Shape.h"
#include <gdiplus.h>
#include <queue>

class CTetrisApp
{
public:
	enum { ID_TETRIS_APP = 100 };

public:
	class Config
	{
	public:
		UINT	itemWidth;
		UINT	itemBoardSize;
		Color	colorBackground;
		Color	colorGrid;
		Color	colorPreview;
		Point	gridPosition;
		Rect	rectLevel;
		Color	colorLevel;
		Rect	rectScore;
		Color	colorScore;
		Rect	rectQueue;
		bool	bShowGrid;

	private:
		friend class CTetrisApp;
		Font	*pFontTitle;
		Font	*pFontText;

	public:
		Config();
		~Config();
	};

private:
	static const int ROW = 18;
	static const int COL = 12;
	Config m_cfg;
	int m_score;
	int m_level;
	bool m_bStarted;
	UINT m_nTimerInterval;

private:
	HWND m_hWnd;
	Gdiplus::Graphics m_graphics;
	Rect m_clientRect;

private:
	struct AreaItem {
		BYTE used;
		Color color;
	} m_area[ROW][COL];

private:
	int m_curX;
	int m_curY;
	CShape m_shape;
	std::queue<int> m_shapesQ;

private:
	void EraseBackground();
    void DrawGrid();
	void DrawPreview(CShape *pShape, Color color);
	void DrawShape(CShape *pShape, int ox, int oy, Color color);
	void ClearShape(CShape *pShape, int ox, int oy);
	void DrawShape(CShape *pShape, int x, int y, int itemWidth, int itemBoardSize, Color color, const Brush& brush);
	void RotateShape(CShape *pShape, bool bLeft = true);
	void MoveShape(CShape *pShape, int dir);
	bool IsOutofBoard(CShape *pShape, int x, int y);
	bool IsReachBoard(CShape *pShape, int x, int y, int dir);
	bool IsConfigValid(const Config *pCfg);
	void UpdateTimer();

	void DrawArea();
	void UpdateArea();
	void UpdateLevel();
	void LevelUp();
	void UpdateScore(int nCompleted);
	void CreateNewShape();

	void DrawTitledBox(const RectF &rect, ATL::CString title, ATL::CString text);
	void DrawLevel();
	void DrawScore();
	void DrawQueuedShape();

	void PlaySnd(UINT resID);

public:
	CTetrisApp(HWND hwnd, const Rect &clientRect, const Config *pCfg = NULL);
	~CTetrisApp();
	void Start();
	void Paint();
	void OnKeydown(WPARAM wParam);
	void OnTimer();
	void Gameover();
};

#endif
